//
// Created by Administrator on 2020/6/20 0020.
//
#include <common.h>
#include <detect.h>

jstring char2jstring(JNIEnv *jniEnv, char *ch) {

    return (*jniEnv)->NewStringUTF(jniEnv, ch);
}

jbyteArray char2jbyteArray(JNIEnv *jniEnv, char *data, int length) {

    jbyte *by = (jbyte *) data;
    jbyteArray jarray = (*jniEnv)->NewByteArray(jniEnv, length);
    (*jniEnv)->SetByteArrayRegion(jniEnv, jarray, 0, length, by);
    return jarray;
}

jbyteArray jstring2jbyteArray(JNIEnv *jniEnv, jstring data) {

    jclass String_clazz = NULL;
    static jmethodID String_clazz_getBytes = NULL;

    String_clazz = (*jniEnv)->FindClass(jniEnv, "java/lang/String");

    if (String_clazz_getBytes == NULL) {
        String_clazz_getBytes = (*jniEnv)->GetMethodID(jniEnv, String_clazz, "getBytes",
                                                       "()[B");
        checkExc(jniEnv);
    }
    jbyteArray array = (jbyteArray) (*jniEnv)->CallObjectMethod(jniEnv, data,
                                                                String_clazz_getBytes);
    (*jniEnv)->DeleteLocalRef(jniEnv, String_clazz);
    return array;
}

char *jstring2char(JNIEnv *jniEnv, jstring data) {

    if (jniEnv == NULL || data == NULL) {
        return NULL;
    }
    static jmethodID string_getBytes;
    jclass string_clazz = (*jniEnv)->FindClass(jniEnv, "java/lang/String");
    checkExc(jniEnv);
    jstring strencode = (*jniEnv)->NewStringUTF(jniEnv, "utf-8");
    if (string_getBytes == NULL) {
        string_getBytes = (*jniEnv)->GetMethodID(jniEnv, string_clazz, "getBytes",
                                                 "(Ljava/lang/String;)[B");
        checkExc(jniEnv);
    }

    jbyteArray barr = (jbyteArray) (*jniEnv)->CallObjectMethod(jniEnv, data,
                                                               string_getBytes, strencode);
    jsize alen = (*jniEnv)->GetArrayLength(jniEnv, barr);
    jbyte *ba = (*jniEnv)->GetByteArrayElements(jniEnv, barr, JNI_FALSE);
    char *ret;
    if (alen > 0) {
        ret = malloc(alen + 1);
        memcpy(ret, ba, alen);
        ret[alen] = 0;
    }
    (*jniEnv)->ReleaseByteArrayElements(jniEnv, barr, ba, 0);
    return ret;
}

jbyteArray decode(JNIEnv *jniEnv, jstring data) {

    static jmethodID Base64Utils_decode;
    jclass Base64Utils;
    Base64Utils = (*jniEnv)->FindClass(jniEnv, "com/security/encrypt/b64");
    checkExc(jniEnv);

    if (Base64Utils_decode == NULL) {

        Base64Utils_decode = (*jniEnv)->GetStaticMethodID(jniEnv, Base64Utils, "decode",
                                                          "(Ljava/lang/String;)[B");
        checkExc(jniEnv);
    }

    jbyteArray ret = (*jniEnv)->CallStaticObjectMethod(jniEnv, Base64Utils, Base64Utils_decode,
                                                       data);
    (*jniEnv)->DeleteLocalRef(jniEnv, Base64Utils);
    return ret;
}

jstring encode(JNIEnv *jniEnv, jbyteArray bytes) {

    static jmethodID Base64Utils_encode;
    jclass Base64Utils;
    Base64Utils = (*jniEnv)->FindClass(jniEnv, "com/security/encrypt/b64");
    checkExc(jniEnv);

    if (Base64Utils_encode == NULL) {
        Base64Utils_encode = (*jniEnv)->GetStaticMethodID(jniEnv, Base64Utils, "encode",
                                                          "([B)Ljava/lang/String;");
        checkExc(jniEnv);
    }

    jstring ret = (*jniEnv)->CallStaticObjectMethod(jniEnv, Base64Utils, Base64Utils_encode, bytes);
    (*jniEnv)->DeleteLocalRef(jniEnv, Base64Utils);
    return ret;
}

bool jstringIsEmpty(JNIEnv *jniEnv, jstring str) {
    //TextUtils.isEmpty(keySrc);
    static jmethodID TextUtils_isEmpty;
    jclass TextUtils = (*jniEnv)->FindClass(jniEnv, "android/text/TextUtils");
    checkExc(jniEnv);

    if (TextUtils_isEmpty == NULL) {
        TextUtils_isEmpty = (*jniEnv)->GetStaticMethodID(jniEnv, TextUtils, "isEmpty",
                                                         "(Ljava/lang/CharSequence;)Z");
        checkExc(jniEnv);
    }

    jboolean ret = (*jniEnv)->CallStaticBooleanMethod(jniEnv, TextUtils, TextUtils_isEmpty, str);
    return ret == JNI_TRUE;
}

void throwIllegalArgumentException(JNIEnv *jniEnv, char *exception) {

    jclass IllegalArgumentException = (*jniEnv)->FindClass(jniEnv,
                                                           "java/lang/IllegalArgumentException");
    checkExc(jniEnv);
    (*jniEnv)->ThrowNew(jniEnv, IllegalArgumentException,
                        exception);
}

char *jbyteArray2char(JNIEnv *env, jbyteArray array) {

    jbyte *bytes = (*env)->GetByteArrayElements(env, array, 0);
    int arrayLength = (*env)->GetArrayLength(env, array);
    char *chars = malloc(arrayLength + 1);
    memset(chars, 0x0, arrayLength + 1);
    memcpy(chars, bytes, arrayLength);
    chars[arrayLength] = 0;
    (*env)->ReleaseByteArrayElements(env, array, bytes, 0);

    return chars;
}

